home *** CD-ROM | disk | FTP | other *** search
/ Workbench Add-On / Workbench Add-On - Volume 1.iso / BBS-Archive / Comm / AmiTCP30b2.lha / src / util / finger / util.c < prev   
C/C++ Source or Header  |  1994-02-24  |  8KB  |  337 lines

  1. RCS_ID_C = "$Id: util.c,v 6.5 1994/02/21 19:30:06 ppessi Exp $";
  2.  
  3. /*
  4.  * util.c - Utility functions for finger
  5.  *
  6.  * Copyright © 1993 AmiTCP/IP Group, <AmiTCP-group@hut.fi>
  7.  *                  Helsinki University of Technology, Finland.
  8.  *
  9.  * This program is derived from original work distributed in BSD Net 2.
  10.  *
  11.  * Created      : Fri Oct 15 01:29:07 1993 ppessi
  12.  * Last modified: Mon Feb 21 03:18:04 1994 ppessi
  13.  *
  14.  * $Log: util.c,v $
  15.  * Revision 6.5  1994/02/21  19:30:06  ppessi
  16.  * Removed tty field. Real release 2.
  17.  *
  18.  * Revision 6.4  1994/02/15  14:56:43  ppessi
  19.  * Added utmp support
  20.  *
  21.  * Revision 6.3  1994/01/21  13:38:03  ppessi
  22.  * Enabled "fuzzy" matching
  23.  *
  24.  * Revision 6.2  93/10/15  03:01:49  ppessi
  25.  * Polished AmiTCP support
  26.  * 
  27.  */
  28.  
  29. /*
  30.  * Copyright (c) 1989 The Regents of the University of California.
  31.  * All rights reserved.
  32.  *
  33.  * This code is derived from software contributed to Berkeley by
  34.  * Tony Nardo of the Johns Hopkins University/Applied Physics Lab.
  35.  *
  36.  * Redistribution and use in source and binary forms, with or without
  37.  * modification, are permitted provided that the following conditions
  38.  * are met:
  39.  * 1. Redistributions of source code must retain the above copyright
  40.  *    notice, this list of conditions and the following disclaimer.
  41.  * 2. Redistributions in binary form must reproduce the above copyright
  42.  *    notice, this list of conditions and the following disclaimer in the
  43.  *    documentation and/or other materials provided with the distribution.
  44.  * 3. All advertising materials mentioning features or use of this software
  45.  *    must display the following acknowledgement:
  46.  *    This product includes software developed by the University of
  47.  *    California, Berkeley and its contributors.
  48.  * 4. Neither the name of the University nor the names of its contributors
  49.  *    may be used to endorse or promote products derived from this software
  50.  *    without specific prior written permission.
  51.  *
  52.  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  53.  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  54.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  55.  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  56.  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  57.  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  58.  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  59.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  60.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  61.  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  62.  * SUCH DAMAGE.
  63.  */
  64.  
  65. static char sccsid[] = "@(#)util.c    5.14 (Berkeley) 1/17/91";
  66.  
  67. #include <sys/param.h>
  68. #include <sys/time.h>
  69. #include <stdlib.h>
  70. #include <stdio.h>
  71. #include <ctype.h>
  72. #include <string.h>
  73. #if AMIGA
  74. #include <proto/usergroup.h>
  75. #endif
  76. #include "finger.h"
  77.  
  78. char *strsep(register char **stringp, register const char *delim);
  79.  
  80. /* This pulls the gettimeofday() from net.lib */
  81. time_t time(time_t *tp) 
  82. {
  83.   struct timeval tv[1];
  84.  
  85.   gettimeofday(tv, NULL);
  86.  
  87.   if (tp) *tp = tv->tv_sec;
  88.  
  89.   return tv->tv_sec;
  90. }
  91.  
  92. /* Local prototypes */
  93. int hash(register char *name);
  94.  
  95. void
  96. userinfo( register PERSON *pn, register struct passwd *pw)
  97. {
  98.   register char *p, *t;
  99.   char *bp, name[1024];
  100.  
  101.   pn->realname = pn->office = pn->officephone = pn->homephone = NULL;
  102.  
  103.   pn->uid = pw->pw_uid;
  104.   pn->name = strdup(pw->pw_name);
  105.   pn->dir = strdup(pw->pw_dir);
  106.   pn->shell = strdup(pw->pw_shell);
  107.  
  108.   /* why do we skip asterisks!?!? */
  109.   (void)strcpy(bp = tbuf, pw->pw_gecos);
  110.   if (*bp == '*')
  111.     ++bp;
  112.  
  113.   /* ampersands get replaced by the login name */
  114.   if (!(p = strsep(&bp, ",")))
  115.     return;
  116.   for (t = name; *t = *p; ++p)
  117.     if (*t == '&') {
  118.       (void)strcpy(t, pw->pw_name);
  119.       if (islower(*t))
  120.     *t = toupper(*t);
  121.       while (*++t);
  122.     }
  123.     else
  124.       ++t;
  125.   pn->realname = strdup(name);
  126.   pn->office = ((p = strsep(&bp, ",")) && *p) ?
  127.     strdup(p) : NULL;
  128.   pn->officephone = ((p = strsep(&bp, ",")) && *p) ?
  129.     strdup(p) : NULL;
  130.   pn->homephone = ((p = strsep(&bp, ",")) && *p) ?
  131.     strdup(p) : NULL;
  132. }
  133.  
  134. int match(struct passwd *pw, char *user)
  135. {
  136.   register char *p, *t;
  137.   char name[1024];
  138.  
  139.   /* why do we skip asterisks!?!? */
  140.   (void)strcpy(p = tbuf, pw->pw_gecos);
  141.   if (*p == '*')
  142.     ++p;
  143.  
  144.   /* ampersands get replaced by the login name */
  145.   if (!(p = strtok(p, ",")))
  146.     return(0);
  147.   for (t = name; *t = *p; ++p)
  148.     if (*t == '&') {
  149.       (void)strcpy(t, pw->pw_name);
  150.       while (*++t);
  151.     }
  152.     else
  153.       ++t;
  154.   for (t = name; p = strtok(t, "\t "); t = (char *)NULL)
  155.     if (!strcasecmp(p, user))
  156.       return(1);
  157.   return(0);
  158. }
  159.  
  160. void
  161. enter_lastlog(register PERSON *pn)
  162. {
  163.   register WHERE *w;
  164.   struct lastlog *ll = getlastlog(pn->uid);
  165.   int doit = 0;
  166.  
  167.   if ((w = pn->whead) == NULL)
  168.     doit = 1;
  169.   else if (ll->ll_time != 0) {
  170.     /* if last login is earlier than some current login */
  171.     for (; !doit && w != NULL; w = w->next)
  172.       if (w->info == LOGGEDIN && w->loginat < ll->ll_time)
  173.     doit = 1;
  174.     /*
  175.      * and if it's not any of the current logins
  176.      */
  177.     for (w = pn->whead; doit && w != NULL; w = w->next)
  178.       if (w->info == LOGGEDIN && w->loginat == ll->ll_time)
  179.     doit = 0;
  180.   }
  181.   if (doit) {
  182.     w = walloc(pn);
  183.     w->info = LASTLOG;
  184. #ifdef HAVE_TTY
  185.     bcopy(ll->ll_line, w->tty, UT_LINESIZE);
  186.     w->tty[UT_LINESIZE] = 0;
  187. #endif
  188.     bcopy(ll->ll_host, w->host, UT_HOSTSIZE);
  189.     w->host[UT_HOSTSIZE] = 0;
  190.     w->loginat = ll->ll_time;
  191.   }
  192. }
  193.  
  194. void
  195. enter_where(struct utmp *ut, PERSON *pn)
  196. {
  197.   register WHERE *w = walloc(pn);
  198.   w->info = LOGGEDIN;
  199. #ifdef HAVE_TTY
  200.   bcopy(ut->ut_line, w->tty, UT_LINESIZE);
  201.   w->tty[UT_LINESIZE] = 0;
  202. #endif
  203.   bcopy(ut->ut_host, w->host, UT_HOSTSIZE);
  204.   w->host[UT_HOSTSIZE] = 0;
  205.   w->loginat = (time_t)ut->ut_time;
  206. }
  207.  
  208. PERSON *
  209. enter_person(register struct passwd *pw)
  210. {
  211.   register PERSON *pn, **pp;
  212.  
  213.   for (pp = htab + hash(pw->pw_name);
  214.        *pp != NULL && strcmp((*pp)->name, pw->pw_name) != 0;
  215.        pp = &(*pp)->hlink)
  216.     ;
  217.   if ((pn = *pp) == NULL) {
  218.     pn = palloc();
  219.     entries++;
  220.     if (phead == NULL)
  221.       phead = ptail = pn;
  222.     else {
  223.       ptail->next = pn;
  224.       ptail = pn;
  225.     }
  226.     pn->next = NULL;
  227.     pn->hlink = NULL;
  228.     *pp = pn;
  229.     userinfo(pn, pw);
  230.     pn->whead = NULL;
  231.   }
  232.   return(pn);
  233. }
  234.  
  235. PERSON *
  236. find_person(char *name)
  237. {
  238.   register PERSON *pn;
  239.  
  240.   /* name may be only UT_NAMESIZE long and not terminated */
  241.   for (pn = htab[hash(name)];
  242.        pn != NULL && strncmp(pn->name, name, UT_NAMESIZE) != 0;
  243.        pn = pn->hlink)
  244.     ;
  245.   return(pn);
  246. }
  247.  
  248. int
  249. hash(register char *name)
  250. {
  251.   register int h, i;
  252.  
  253.   h = 0;
  254.   /* name may be only UT_NAMESIZE long and not terminated */
  255.   for (i = UT_NAMESIZE; --i >= 0 && *name;)
  256.     h = ((h << 2 | h >> HBITS - 2) ^ *name++) & HMASK;
  257.   return(h);
  258. }
  259.  
  260. PERSON *
  261. palloc(void)
  262. {
  263.   PERSON *p;
  264.  
  265.   if ((p = (PERSON *)malloc((u_int) sizeof(PERSON))) == NULL) {
  266.     (void)fprintf(stderr, "finger: out of space.\n");
  267.     exit(1);
  268.   }
  269.   return(p);
  270. }
  271.  
  272. WHERE *
  273. walloc(register PERSON *pn)
  274. {
  275.   register WHERE *w;
  276.  
  277.   if ((w = (WHERE *)malloc((u_int) sizeof(WHERE))) == NULL) {
  278.     (void)fprintf(stderr, "finger: out of space.\n");
  279.     exit(1);
  280.   }
  281.   if (pn->whead == NULL)
  282.     pn->whead = pn->wtail = w;
  283.   else {
  284.     pn->wtail->next = w;
  285.     pn->wtail = w;
  286.   }
  287.   w->next = NULL;
  288.   return(w);
  289. }
  290.  
  291. char *
  292. prphone(char *num)
  293. {
  294.   register char *p;
  295.   int len;
  296.   static char pbuf[15];
  297.  
  298.   /* don't touch anything if the user has their own formatting */
  299.   for (p = num; *p; ++p)
  300.     if (!isdigit(*p))
  301.       return(num);
  302.   len = p - num;
  303.   p = pbuf;
  304.   switch(len) {
  305.   case 11:            /* +0-123-456-7890 */
  306.     *p++ = '+';
  307.     *p++ = *num++;
  308.     *p++ = '-';
  309.     /* FALLTHROUGH */
  310.   case 10:            /* 012-345-6789 */
  311.     *p++ = *num++;
  312.     *p++ = *num++;
  313.     *p++ = *num++;
  314.     *p++ = '-';
  315.     /* FALLTHROUGH */
  316.   case 7:            /* 012-3456 */
  317.     *p++ = *num++;
  318.     *p++ = *num++;
  319.     *p++ = *num++;
  320.     break;
  321.   case 5:            /* x0-1234 */
  322.     *p++ = 'x';
  323.     *p++ = *num++;
  324.     break;
  325.   default:
  326.     return(num);
  327.   }
  328.   *p++ = '-';
  329.   *p++ = *num++;
  330.   *p++ = *num++;
  331.   *p++ = *num++;
  332.   *p++ = *num++;
  333.   *p = '\0';
  334.   return(pbuf);
  335. }
  336.  
  337.